/**
 * 
 */
package algo3c2g15.domain;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;


import algo3c2g15.utils.Matematica;

/**
 * @author De La
 *
 */
public abstract class Transporte extends Unidad {
	private Integer capacidad = new Integer(0);
	private ArrayList<Humano> pasajeros = new ArrayList<Humano>();
	private Integer pasajerosABordo = new Integer(0);
	
	protected Transporte() {
	}
	
	protected Transporte(Element xmlElement) throws Exception  {
		super(xmlElement);
		this.setCapacidad(Integer.parseInt(xmlElement.getAttribute("capacidad")));
		
		NodeList nodoUnidades = xmlElement.getElementsByTagName("PASAJEROS").item(0).getChildNodes();
		
		for(int nUnidades=0; nUnidades < nodoUnidades.getLength(); nUnidades++){
			Element elemUnidad = (Element) nodoUnidades.item(nUnidades);
					
			Class argumentos[] = new Class[1];
			argumentos[0] = Class.forName("org.w3c.dom.Element");
			Constructor constructor = Class.forName(elemUnidad.getAttribute("clase")).getConstructor(argumentos);
			Object arg[] = new Object[1];
			arg[0] = elemUnidad;
			Humano humano = (Humano) constructor.newInstance(arg);
			this.subirPasajero(humano);
		}
	}
	
	/**
	 * @return the capacidad
	 */
	public Integer getCapacidad() {
		return capacidad;
	}
	/**
	 * @param capacidad the capacidad to set
	 */
	public void setCapacidad(Integer capacidad) {
		this.capacidad = capacidad;
	}
	/**
	 * @return the pasajeros
	 */
	public ArrayList<Humano> getPasajeros() {
		return pasajeros;
	}
	/**
	 * @param pasajeros the pasajeros to set
	 */
	public void setPasajeros(ArrayList<Humano> pasajeros) {
		this.pasajeros = pasajeros;
	}
	/**
	 * @return the pasajerosABordo
	 */
	public Integer getPasajerosABordo() {
		return pasajerosABordo;
	}
	/**
	 * @param pasajerosABordo the pasajerosABordo to set
	 */
	public void setPasajerosABordo(Integer pasajerosABordo) {
		this.pasajerosABordo = pasajerosABordo;
	}
	/**
	 * Devuelva la cantidad de pasajeros q todavia pueden a bordar
	 */
	public Integer getCapacidadRestante() {
		return (capacidad - pasajerosABordo);
	}
	/**
	 * Sube un pasajero al transporte
	 * devuelve true si lo pudo subir, de lo contrario false
	 */
	public boolean subirPasajero(Humano pasajero){
		if (getCapacidadRestante()>0){
			pasajeros.add(pasajero);
			pasajerosABordo += 1;
			return true;
		}
		else
			return false;
	}
	/**
	 * Sube los pasajeros al transporte
	 * devuelve true si lo pudo subir, de lo contrario false
	 */
	public boolean subirPasajero(Collection<Humano> pasajeros){
		if (getCapacidadRestante() > pasajeros.size()){
			this.pasajeros.addAll(pasajeros);
			pasajerosABordo += pasajeros.size();
			return true;
		}
		else
			return false;
	}
	/**
	 * Saca el pasajero deseado del transporte
	 */
	public void sacarPasajero(Humano pasajero){
		pasajeros.remove(pasajero);
	}
	/**
	 * Saca los pasajeros deseados del transporte
	 */
	public void sacarPasajero(Collection<Humano> pasajeros){
		this.pasajeros.removeAll(pasajeros);
	}
	
	/**
	 * el transporte recibe un 75% del ataque y
	 * los pasajeros se reparten en partes iguales
	 * el 25% restante del ataque
	 */
	public void daniar(Double danio) {
		Integer pasajerosVivos = 0;
		
		if (getPasajerosABordo() > 0){
			for (Humano pasajero : getPasajeros()){
				if (pasajero.vivo())
				pasajerosVivos++;
			}
		}
		
		Double coeficiente = 0.1 * pasajerosVivos;
		
		setVida( Matematica.redondiarADosDecimales( getVida()-danioConDefensa( danio*(1-coeficiente) ) ) );
		
		if (getPasajerosABordo() > 0){
			for (Humano pasajero : getPasajeros()){
				if (pasajero.vivo())
					pasajero.daniar(danio*0.1);
			}
		}
	}
	
	public Element getElementXml(Document doc) {
		Element elemTransporte = super.getElementXml(doc);
		Element pasajerosABordoXML = doc.createElement("PASAJEROS");
		
		elemTransporte.setAttribute("capacidad", getCapacidad().toString());
		elemTransporte.setAttribute("pasajerosABordo", getPasajerosABordo().toString());
		
		for (Humano pasajero : getPasajeros()){
			pasajerosABordoXML.appendChild(pasajero.getElementXml(doc));
		}
		elemTransporte.appendChild(pasajerosABordoXML);
		
		return elemTransporte;
		
	}
}
